﻿using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using EFCore.BulkExtensions;

using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;

namespace Hang.Blog.DomainPlus.Imp {
    public class ExtendRepository<TDbContext, T> : EfCoreRepository<TDbContext, T>, IExtendRepository<TDbContext, T> where T : class, IEntity where TDbContext : AbpDbContext<TDbContext> {
        public ExtendRepository(IDbContextProvider<TDbContext> dbContextProvider) : base(dbContextProvider) {
        }

        public async Task BulkDeleteAsync(IEnumerable<T> datas) {
            if (datas.Any()) {
                var context = await GetDbContextAsync();
                await context.SaveChangesAsync();
                await context.BulkDeleteAsync(datas.ToList());
                await context.BulkSaveChangesAsync();
            }
        }

        public async Task BulkInsertAsync(IEnumerable<T> datas) {
            if (datas.Any()) {
                var context = await GetDbContextAsync();
                await context.SaveChangesAsync();
                await context.BulkInsertAsync(datas.ToList());
                await context.BulkSaveChangesAsync();
            }
        }

        public async Task BulkUpdateAsync(IEnumerable<T> datas) {
            if (datas.Any()) {
                var ctx = await GetDbContextAsync();
                await ctx.SaveChangesAsync();
                await ctx.BulkUpdateAsync(datas.ToList());
                await ctx.BulkSaveChangesAsync();
                await ctx.SaveChangesAsync();
            }
        } 
    }

    public class ExtendRepository<TDbContext, T, TKey> : EfCoreRepository<TDbContext, T, TKey>, IExtendRepository<TDbContext, T, TKey> where T : class, IEntity<TKey> where TDbContext : AbpDbContext<TDbContext> {
        public ExtendRepository(IDbContextProvider<TDbContext> dbContextProvider) : base(dbContextProvider) {
        }

        public async Task BulkDeleteAsync(IEnumerable<T> datas) {
            if (datas.Any()) {
                var context = await GetDbContextAsync();
                using (var transaction = context.Database.BeginTransaction()) {
                    await context.SaveChangesAsync();
                    await context.BulkDeleteAsync(datas.ToList());
                    await context.BulkSaveChangesAsync();
                    await transaction.CommitAsync();
                }
            }
        }

        public async Task BulkInsertAsync(IEnumerable<T> datas) {
            if (datas.Any()) {
                var context = await GetDbContextAsync();
                using (var transaction = context.Database.BeginTransaction()) {
                    await context.SaveChangesAsync();
                    await context.BulkInsertAsync(datas.ToList());
                    await context.BulkSaveChangesAsync();
                    await transaction.CommitAsync();
                }
            }

        }

        public async Task BulkUpdateAsync(IEnumerable<T> datas) {
            if (datas.Any()) {
                var ctx = await GetDbContextAsync();
                await ctx.SaveChangesAsync();
                await ctx.BulkUpdateAsync(datas.ToList());
                await ctx.BulkSaveChangesAsync();
                await ctx.SaveChangesAsync();
            }
        }

    }


}
